package com.demo.common.dynamic.datasource.utils;

import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * 自定义多数据源实体类
 *
 * @author molong
 * @date 2021/10/22
 */
@Slf4j
public class DynamicDataSource extends AbstractRoutingDataSource {
    /**
     * 单例对象
     */
    private static DynamicDataSource INSTANCE;
    /**
     * 数据源实例的缓存
     */
    private final Map<Object, Object> dataSourceMap = new HashMap<>();

    @Override
    protected Object determineCurrentLookupKey() {
        String dsKey = DsContextHolder.getCurrentDataSourceKey();
        if (StrUtil.isNotEmpty(dsKey)) {
            if (dataSourceMap.containsKey(dsKey)) {
                log.debug("当前数据源：" + dsKey);
            } else {
                log.debug("不存在的数据源:" + dsKey);
                return null;
            }
        }
        return dsKey;
    }


    /**
     * 设置数据源
     *
     * @param targetDataSources 数据源
     */
    @Override
    public void setTargetDataSources(Map<Object, Object> targetDataSources) {
        super.setTargetDataSources(targetDataSources);
    }

    /**
     * 添加数据源
     *
     * @param key           数据源唯一标识
     * @param addDataSource 新增数据源
     */
    public void addDataSource(String key, Object addDataSource) {
        dataSourceMap.put(key, addDataSource);
        setTargetDataSources(dataSourceMap);
    }

    /**
     * 判断数据源是否存在
     *
     * @param dataSourceKey 数据源唯一标识
     * @return 是否存在
     */
    public boolean isExist(String dataSourceKey) {
        return dataSourceMap.containsKey(dataSourceKey);
    }

    /**
     * 单例方法
     *
     * @return 单例对象
     */
    public static synchronized DynamicDataSource getInstance() {
        if (INSTANCE == null) {
            synchronized (DynamicDataSource.class) {
                if (INSTANCE == null) {
                    INSTANCE = new DynamicDataSource();
                }
            }
        }
        return INSTANCE;
    }

    /**
     * 创建数据源
     *
     * @param dataSourceKey 数据源唯一标识
     * @param url           数据源连接
     * @param username      数据源连接用户名
     * @param password      数据源连接密码
     */
    public void createDataSource(String dataSourceKey, String url, String username, String password) {
        DataSourceBuilder<?> dataSourceBuilder = DataSourceBuilder.create();
        dataSourceBuilder.url(url);
        dataSourceBuilder.username(username);
        dataSourceBuilder.password(password);
        DataSource dataSource = dataSourceBuilder.build();

        //创建数据源
        addDataSource(dataSourceKey, dataSource);
        // 必须添加该句，否则新添加数据源无法识别到
        super.afterPropertiesSet();
        log.debug("数据源【" + dataSourceKey + "】初始化成功");
    }

    /**
     * 删除数据源
     *
     * @param dataSourceKey 数据源唯一标识
     */
    public void delDataSource(String dataSourceKey) {
        if (dataSourceMap.containsKey(dataSourceKey)) {
            dataSourceMap.remove(dataSourceKey);
            setTargetDataSources(dataSourceMap);
            // 必须添加该句，否则新添加数据源无法识别到
            super.afterPropertiesSet();
        }
    }

}
